package com.healthcloud.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.healthcloud.constants.UserConsts;
import com.healthcloud.dao.*;
import com.healthcloud.dao.PatientRecord.MedicalCheckDao;
import com.healthcloud.dao.PatientRecord.MedicalTestDao;
import com.healthcloud.dao.RegionalDisease.TestprojectitemmonitorDao;
import com.healthcloud.dao.accompany.*;
import com.healthcloud.dao.losewisdom.*;
import com.healthcloud.dao.patient.*;
import com.healthcloud.dao.questionnaire.QuestionnaireRecordDao;
import com.healthcloud.dao.rent.InstrumentWechatDao;
import com.healthcloud.dao.screening.ScreeningBlDao;
import com.healthcloud.dao.screening.ScreeningBpDao;
import com.healthcloud.dao.screening.ScreeningBsDao;
import com.healthcloud.entity.*;
import com.healthcloud.entity.PatientRecord.PatientInfoVo;
import com.healthcloud.service.PpPatientBaseService;
import com.healthcloud.service.SysUserService;
import com.healthcloud.utils.Constant;
import com.healthcloud.utils.PageParam;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service("ppPatientBaseService")
@Transactional
public class PpPatientBaseServiceImpl implements PpPatientBaseService {
	@Autowired
	private PpPatientBaseDao ppPatientBaseDao;

	@Autowired
	private PpPatientNewaddDao patientNewaddDao;

	@Autowired
	private SysUserService sysUserService;


	@Autowired
	private AccompanyBfDao accompanyBfDao;
	@Autowired
	private AccompanyBlDao accompanyBlDao;
	@Autowired
	private AccompanyBlNoMedicalDao accompanyBlNoMedicalDao;
	@Autowired
	private AccompanyBpDao accompanyBpDao;
	@Autowired
	private AccompanyBsDao accompanyBsDao;
	@Autowired
	private BoneLooseCheckDao boneLooseCheckDao;
	@Autowired
	private BoneLooseDrugDao boneLooseDrugDao;
	@Autowired
	private BoneLooseResultDao boneLooseResultDao;
	@Autowired
	private PatientBloodFatDao patientBloodFatDao;
	@Autowired
	private PatientDataDao patientDataDao;
	@Autowired
	private PatientDataSpecDao patientDataSpecDao;
	@Autowired
	private LoseWisdomAdieDao loseWisdomAdieDao;
	@Autowired
	private LoseWisdomBarthelAdlDao loseWisdomBarthelAdlDao;
	@Autowired
	private LoseWisdomBpslDao loseWisdomBpslDao;
	@Autowired
	private LoseWisdomFollowUpDao loseWisdomFollowUpDao;
	@Autowired
	private LoseWisdomMmseDao loseWisdomMmseDao;
	@Autowired
	private LoseWisdomReportCardDao loseWisdomReportCardDao;
	@Autowired
	private LoseWisdomScreeningGadDao loseWisdomScreeningGadDao;
	@Autowired
	private LoseWisdomScreeningPhqDao loseWisdomScreeningPhqDao;
	@Autowired
	private MedicalCheckDao medicalCheckDao;
	@Autowired
	private MedicalTestDao medicalTestDao;
	@Autowired
	private QuestionnaireRecordDao questionnaireRecordDao;
	@Autowired
	private ScreeningBlDao screeningBlDao;
	@Autowired
	private ScreeningBpDao screeningBpDao;
	@Autowired
	private ScreeningBsDao screeningBsDao;
	@Autowired
	private TestprojectitemmonitorDao testprojectitemmonitorDao;
//	@Autowired
//	private PpPatientBaseDao ppPatientBaseDao;
	@Autowired
	private TestresultDao testresultDao;
	@Autowired
	private BusRentDao busRentDao;
	@Autowired
	private BusInstrumentDao instrumentInfoDao;

	@Override
	public PpPatientBaseEntity queryObject(Integer id){
		return ppPatientBaseDao.queryObject(id);
	}

	@Override
	public List<PpPatientBaseVo> queryListVo(PpPatientBaseVo entity, PageParam pageParam){
		return ppPatientBaseDao.queryListVo(entity, pageParam);
	}

	@Override
	public int queryTotalVo(PpPatientBaseVo entity){
		return ppPatientBaseDao.queryTotalVo(entity);
	}

	@Override
	public void save(PpPatientBaseEntity ppPatientBase){
		ppPatientBase.setCreatedtime(new Date());
		ppPatientBase.setUpdatedtime(new Date());
		ppPatientBaseDao.save(ppPatientBase);


		//注册用户基本信息，默认为医生账号
		SysUserEntity user = new SysUserEntity();
		if(StringUtils.isBlank(ppPatientBase.getPhone())){

			user.setUsername(ppPatientBase.getIdcard());
			user.setMobile(Constant.DEFAULT_MOBILE);
		}else{
			user.setUsername(ppPatientBase.getPhone());
			user.setMobile(ppPatientBase.getPhone());
		}
		user.setRealName(ppPatientBase.getRealname());
		user.setPassword(Constant.DEFAULT_PWD);
		user.setStatus(UserConsts.STATE_NORMAL);
		user.setUserKind(UserConsts.KIND_NORMAL);
		SysRoleEntity roleEntity = new SysRoleEntity();
		roleEntity.setRoleId(UserConsts.ROLE_PATIENT);
		List<SysRoleEntity> sysRoleEntities = new ArrayList<>();
		sysRoleEntities.add(roleEntity);
		user.setRoleList(sysRoleEntities);
		sysUserService.save(user);
	}

	@Override
	public void update(PpPatientBaseEntity ppPatientBase){
		ppPatientBase.setUpdatedtime(new Date());
		ppPatientBaseDao.update(ppPatientBase);
		String diseases = ppPatientBase.getDiseasesType();
		if(diseases != null && diseases.length() > 0){
			List<String>  arrList= Arrays.asList(diseases.split(",").clone());
			List diseasesTypeAdd = new ArrayList(arrList);
			List diseasesTypedele = new ArrayList(arrList);
			List<PpPatientNewadd> list = patientNewaddDao.queryListByIdCards(ppPatientBase.getIdcard());
			if (list.size()>0){
				List<String> lista = new ArrayList<String>();
				List listadd = new ArrayList(lista);
				for(PpPatientNewadd pp:list){
					listadd.add(pp.getDiseasesType());
				}
				diseasesTypeAdd.removeAll(listadd);
				if (diseasesTypeAdd.size()>0){
					for(Object s:diseasesTypeAdd){
						PpPatientNewadd ppPatientNewadd = new PpPatientNewadd();
						ppPatientNewadd.setDiseasesType(s.toString());
						ppPatientNewadd.setUpdatedTime(new Date());
						ppPatientNewadd.setIdCard(ppPatientBase.getIdcard());
						ppPatientNewadd.setHospitalId(ppPatientBase.getHospitalId());
						patientNewaddDao.add(ppPatientNewadd);
					}
				}
				listadd.removeAll(diseasesTypedele);
				if (listadd.size()>0){
					for(Object s:listadd){
						patientNewaddDao.deletep(s.toString(),ppPatientBase.getIdcard());
					}

				}
			}else {
				for(Object s:diseasesTypeAdd){
					PpPatientNewadd ppPatientNewadd = new PpPatientNewadd();
					ppPatientNewadd.setDiseasesType(s.toString());
					ppPatientNewadd.setUpdatedTime(new Date());
					ppPatientNewadd.setIdCard(ppPatientBase.getIdcard());
					ppPatientNewadd.setHospitalId(ppPatientBase.getHospitalId());
					patientNewaddDao.add(ppPatientNewadd);
				}

			}
		}
	}

	@Override
	public void delete(Integer id){
		ppPatientBaseDao.delete(id);
	}

	@Override
	public void deleteBatch(Integer[] ids){
		ppPatientBaseDao.deleteBatch(ids);
	}

	@Override
	public PpPatientBaseEntity queryByIdcard(String idcard) {
		return ppPatientBaseDao.queryByIdcard(idcard);
	}

	@Override
	public void add(PpPatientBaseEntity patient) {
		ppPatientBaseDao.add(patient);
	}

	@Override
	public PatientInfoVo searchByIdCard(String idCard) {
		return ppPatientBaseDao.SearchByIdCard(idCard);
	}

	@Override
	public Integer countDiseasesByIds(String ids, String types, Integer age, Integer sex) {
		return ppPatientBaseDao.countDiseasesByIds(ids, types, age, sex);
	}

	@Override
	public Integer countDiseasesByIdsTest(String ids, String testItemCodes, Integer day) {
		return ppPatientBaseDao.countDiseasesByIdsTest(ids, testItemCodes, day);
	}

	/**
	 * 2020-07-06 修改统计标准为：血压未达标总数：
	 * 以最近一次测量的血压值为标准
	 * 104001 对应测量值 >= 135
	 * 104002 对应测量值 >= 85
	 * 135或85有一个指标达到就算未达标
	 *
	 * @param hospIds 医院id
	 * @return
	 */
	@Override
	public Integer countBpErrorNumByIdsTest(String hospIds) {
		// 查询 最近一次测量的高压 104001 对应测量值 >= 135 的身份证号列表
		List<String> error135IdCardList = ppPatientBaseDao.listError135BpIdCards(hospIds);
		// 查询 最近一次测量的低压 104002 对应测量值 >= 85 的身份证号列表
		List<String> error85IdCardList = ppPatientBaseDao.listError85BpIdCards(hospIds);
		// 两个 list 取并集
		Collection<String> unionList = CollUtil.union(error135IdCardList, error85IdCardList);

		return unionList.size();
	}

	/**
	 * 血糖未达标总数 2020-07-06 修改统计标准为：
	 * 以最近一次测量的血糖值为标准
	 * 105001 空腹血糖 （餐前） 对应测量值 >= 7.0
	 * 105002 餐后2小时血糖 对应测量值 >= 10.0
	 * 7.0 或 10.0 有一个指标达到就算未达标
	 *
	 * @param hospIds
	 * @return
	 */
	@Override
	public Integer countBsErrorNum(String hospIds) {
		// 查询 最近一次测量的血糖 105001 空腹血糖 （餐前） 对应测量值 >= 7.0 的身份证号列表
		List<String> error7BsIdCardList = ppPatientBaseDao.listErrorBsIdCards(hospIds, "105001", 7);
		// 查询 最近一次测量的血糖 105002 餐后2小时血糖 对应测量值 >= 10.0 的身份证号列表
		List<String> error10BsIdCards = ppPatientBaseDao.listErrorBsIdCards(hospIds, "105002", 10);
		// 两个 list 取并集
		Collection<String> unionList = CollUtil.union(error7BsIdCardList, error10BsIdCards);

		return unionList.size();
	}

	@Override
	public List<String> listErrorBsIdCards(String hospIds, String testItemCode,Integer standardValue) {
		return ppPatientBaseDao.listErrorBsIdCards(hospIds, testItemCode, standardValue);
	}

	/**
	 * 血糖测量总人数
	 * @param hospIds
	 * @return
	 */
	@Override
	public Integer countBsNum(String hospIds) {
		int num = ppPatientBaseDao.countBsIdCardNum(hospIds);
		return num;
	}


	@Override
	public Integer totalByHospitalIds(String ids) {
		return ppPatientBaseDao.totalByHospitalIds(ids);
	}

	@Override
	public Integer coutByIdsTest(String ids, String testItemCodes) {
		return ppPatientBaseDao.coutByIdsTest(ids, testItemCodes);
	}

	@Override
	public Map countErrorAge(String ids, String testItemCodes) {
		return ppPatientBaseDao.countErrorAge(ids, testItemCodes);
	}

	@Override
	public void savePatient(PpPatientBaseEntity entity) {
		ppPatientBaseDao.savePatient(entity);
		String diseases = entity.getDiseasesType();
		if (diseases.length()>0){
			List<String>  arrList= Arrays.asList(diseases.split(",").clone());
			if (arrList.size()>0){
				for(Object s:arrList){
					PpPatientNewadd ppPatientNewadd = new PpPatientNewadd();
					ppPatientNewadd.setDiseasesType(s.toString());
					ppPatientNewadd.setUpdatedTime(new Date());
					ppPatientNewadd.setIdCard(entity.getIdcard());
					ppPatientNewadd.setHospitalId(entity.getHospitalId());
					patientNewaddDao.add(ppPatientNewadd);
				}
			}
		}


	}

	@Override
	public void savePatientTemp(PpPatientBaseEntity entity) {
		ppPatientBaseDao.savePatientTemp(entity);
	}

	/**
	 * 获取病人最大id
	 * @return
	 */
	@Override
	public Integer getMaxId() {
		return ppPatientBaseDao.getMaxId();
	}


	/**
	 * 修改血压信息
	 * @param entity
	 */
	@Override
	public void updateBpInfo(PpPatientBaseEntity entity) {
		ppPatientBaseDao.updateBpInfo(entity);
	}


	/**
	 * 根据身份证号、hospitalId，查询 pp_patient_base 患者表中是否已有记录
	 * @param idCard
	 * @param hospitalId
	 * @return
	 */
	@Override
	public int countByIdCardAndHospitalId(String idCard, Long hospitalId) {
		return ppPatientBaseDao.countByIdCardAndHospitalId(idCard, hospitalId);
	}

	@Autowired
	private InstrumentWechatDao instrumentWechatDao;
	/**
	 * 修改病人身份证号
	 * @param oldIdCard 修改前身份证号
	 * @param newIdCard 修改后身份证号
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateIdCard(String oldIdCard, String newIdCard) {
		accompanyBfDao.updateIdCard(newIdCard, oldIdCard);
		accompanyBlDao.updateIdCard(newIdCard, oldIdCard);
		accompanyBlNoMedicalDao.updateIdCard(newIdCard, oldIdCard);
		accompanyBpDao.updateIdCard(newIdCard, oldIdCard);
		accompanyBsDao.updateIdCard(newIdCard, oldIdCard);
		boneLooseCheckDao.updateIdCard(newIdCard, oldIdCard);
		boneLooseDrugDao.updateIdCard(newIdCard, oldIdCard);
		boneLooseResultDao.updateIdCard(newIdCard, oldIdCard);
		instrumentInfoDao.updatePatientIdCard(newIdCard, oldIdCard);
		loseWisdomAdieDao.updateIdCard(newIdCard, oldIdCard);
		loseWisdomBarthelAdlDao.updateIdCard(newIdCard, oldIdCard);
		loseWisdomBpslDao.updateIdCard(newIdCard, oldIdCard);
		loseWisdomFollowUpDao.updateIdCard(newIdCard, oldIdCard);
		loseWisdomMmseDao.updateIdCard(newIdCard, oldIdCard);
		loseWisdomReportCardDao.updateIdCard(newIdCard, oldIdCard);
		loseWisdomScreeningGadDao.updateIdCard(newIdCard, oldIdCard);
		loseWisdomScreeningPhqDao.updateIdCard(newIdCard, oldIdCard);
		medicalCheckDao.updateIdCard(newIdCard, oldIdCard);
		medicalTestDao.updateIdCard(newIdCard, oldIdCard);
		ppPatientBaseDao.updateIdCard(newIdCard, oldIdCard);
		patientBloodFatDao.updateIdCard(newIdCard, oldIdCard);
		patientDataSpecDao.updateIdCard(newIdCard, oldIdCard);
		questionnaireRecordDao.updateIdCard(newIdCard, oldIdCard);
		busRentDao.updateIdCard(newIdCard, oldIdCard);
		screeningBlDao.updateIdCard(newIdCard, oldIdCard);
		screeningBpDao.updateIdCard(newIdCard, oldIdCard);
		screeningBsDao.updateIdCard(newIdCard, oldIdCard);
		testprojectitemmonitorDao.updateIdCard(newIdCard, oldIdCard);
		testresultDao.updateIdCard(newIdCard, oldIdCard);
		instrumentWechatDao.updateIdCard(newIdCard, oldIdCard);
	}

	@Override
	public List<bloodPressureExport> querybloodPressureExport(PpPatientBaseVo entity) {
		List<bloodPressureExport> list = ppPatientBaseDao.querybloodPressureExport(entity);
		return list;
	}

	@Override
	public List<bloodSugarExport> querybloodSugarExport(PpPatientBaseVo entity) {
		List<bloodSugarExport> list = ppPatientBaseDao.querybloodSugarExport(entity);
		return list;
	}
}